package com.dcliment.jukebox.controllers
{
	import com.dcliment.controllers.MetricsController;
	import com.dcliment.jukebox.display.gui.SimpleNavButton;
	import com.dcliment.jukebox.display.views.INavView;
	import com.dcliment.jukebox.events.JukeBoxEvent;
	import com.dcliment.jukebox.models.IJukeBoxModel;
	import com.dcliment.jukebox.models.NavButtonModel;
	import com.dcliment.jukebox.models.NavModel;
	import com.dcliment.utils.DisplayObjectUtil;
	import com.dcliment.utils.XMLUtils;
	
	import flash.display.MovieClip;
	import flash.display.Sprite;
	import flash.events.EventDispatcher;
	import flash.events.IEventDispatcher;
	import flash.events.MouseEvent;
	import flash.text.TextFormat;
	import flash.utils.Dictionary;
	
	/**
	 * 
	 * @author dcliment
	 * version 1.0
	 * 
	 */	
	public class JukeNavController extends EventDispatcher
	{
		protected var _jukeBoxModel:IJukeBoxModel;
		protected var _view:Sprite;
		protected var _metricsController:MetricsController;
		protected var _navModel:NavModel;
		// 
		protected var _navBar:MovieClip;
		protected var _navButtons:Array;
		protected var _navDictionary:Dictionary;
		// Appearence
		protected var _onStateTF:TextFormat;
		//
		protected var _activeID:int;
		//
		protected var _activeButton:SimpleNavButton;
		
		public function JukeNavController($model:IJukeBoxModel, $view:Sprite)
		{
			_jukeBoxModel 		= $model;
			_view 				= $view;
			
			_metricsController = MetricsController.getInstance();
			_jukeBoxModel.addEventListener(JukeBoxEvent.ID_CHANGE, onIDChange, false, 0, true);
			
		}
		public function setup($navModel:NavModel):void
		{
			_navModel = $navModel;
			
			var view:Sprite = new Sprite();
				view.x = _navModel.posX;
				view.y = _navModel.posY;
			
			//----------------------
			// nav Bar
			_navBar = DisplayObjectUtil.getLibraryObject("NavBar");
			(_navBar as INavView).init(_navModel.buttonSpacing, _navModel.numOfVisibleButtons,_navModel.button0_x,_navModel.button0_y);
			view.addChild(_navBar);
			
			//----------------------
			// Buttons
			
			// Button onState Color
			if(_navModel.navLabelColorOn)
			{
				_onStateTF = new TextFormat();
				_onStateTF.color = _navModel.navLabelColorOn;
			}
			
			_navButtons = new Array();
			_navDictionary = new Dictionary(false);
			
			var navList:XMLList = _navModel.navList;
			
			for(var i:int = 0; i < navList.length(); i++)
			{
				
				var buttonModel:NavButtonModel = new NavButtonModel();
					buttonModel.label = navList[i];
					buttonModel.id = XMLUtils.getXMLAttribute(navList[i], "id", int, null, true);
					buttonModel.metricsName = XMLUtils.getXMLAttribute(navList[i], "metricsToken", String, null, true);
					
				var nav:SimpleNavButton = createNavButton(buttonModel);
					nav.addEventListener(MouseEvent.CLICK, onNavButtonClicked, false, 0, true);
				
					
				// create a navButtons array to store all the buttons for resetting
				_navButtons.push(nav);
				_navDictionary[buttonModel.id] = nav;
			
				
				// navBar has the function that places the nav where you need it
				(_navBar as INavView).addButton(nav);
			}
			
			_view.addChild(view);
		}
		
		public function reset($currButton:SimpleNavButton):void
		{
			/* 
			this will make sure that the visible button is being showns. So take which versino it is devided by how many visible buttons are 
			allowed and it gives you how many steps it has to move in a direction
			*/
			var n:int = _navButtons.indexOf($currButton)  / _navModel.numOfVisibleButtons; 
			
			(_navBar as INavView).move(n);
			
			for each(var b:SimpleNavButton in _navButtons)
			{
				if(b != $currButton)
					b.enable();
			}
		}
		/**
		 * Here is the tricky point do i
		 * 1) simulate a click event that will activate 
		 * 
		 * 
		 * @param $n :: will end up being the ID which should equal the position in the array its in
		 * 
		 */		
		public function activateButton($n:int):void
		{
		
			var b:SimpleNavButton = _navDictionary[$n] as SimpleNavButton;
				b.onState();
			
			activateB(b);
			
		}
		/**
		 * this streamlines so that even if from mouseEvent or from autoplay activation there is still just one place for the code.
		 * 
		 * @param $b :: button to activate 
		 */		
		protected function activateB($b:SimpleNavButton):void
		{
			var b:SimpleNavButton = $b;
			
			_activeButton = b;
			
			reset(b);
			
			_activeID = b.id;
			_jukeBoxModel.id = b.id;
		}
		///////////////////
		// EVENT LISTENERS
		///////////////////
		protected function onNavButtonClicked(e:MouseEvent):void
		{
			var b:SimpleNavButton = e.currentTarget as SimpleNavButton;
			
			//trace("NavController.onNavButtonClicked = " + b.id + " :: Button token = " + b.token);
			
			// Metrics ~ must happen before _jukeBoxModel.id changes
			_metricsController.recordPage(b.token);
			
			activateB(b);
		}
		protected function onIDChange(e:JukeBoxEvent):void
		{
			if(_activeID != _jukeBoxModel.id)
				this.activateButton(_jukeBoxModel.id);
		}
		//////////////
		// FACTORIES
		/////////////
		protected function createNavButton($buttonModel:NavButtonModel):SimpleNavButton
		{
			var bModel:NavButtonModel = $buttonModel;
						
			// CREATE TITLE
			var b:SimpleNavButton = DisplayObjectUtil.getLibraryObject(_navModel.buttonLinkage) as SimpleNavButton;
				b.id 	= bModel.id;
				b.token = bModel.metricsName;
				b.label = bModel.label;
				b.onStateTF = this._onStateTF;
				
			
			b.addEventListener(MouseEvent.CLICK, onNavButtonClicked, false, 0, true);
			
			return b;
		}
		/////////////
		// ACCESSORS
		/////////////
		public function get activeToken():String
		{
			return _activeButton.token;
		}
		
	}
}